package com.sprite.framework.entity.bridge;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.sprite.framework.entity.transaction.TransactionExecutor;
import com.sprite.framework.entity.transaction.TransactionScript;

/**
 * Spring 事务脚本
 * @author Jack
 */
public class SpringTransactionScript implements TransactionScript{

	private static Logger logger = LoggerFactory.getLogger(SpringTransactionScript.class);
	
	private TransactionStatus transactionStatus;

	private PlatformTransactionManager platformTransactionManager;

	protected SpringTransactionScript(PlatformTransactionManager transactionManager) {
		this.platformTransactionManager = transactionManager;
	}
	
	@Override
	public void begin() {
		if(transactionStatus != null) {
			throw new UnsupportedOperationException(" has begin");
		}
		DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
		definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
		definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
		transactionStatus = platformTransactionManager.getTransaction(definition);
	}

	@Override
	public void rollback() {
		platformTransactionManager.rollback(transactionStatus);
	}

	@Override
	public void commit() {
		platformTransactionManager.commit(transactionStatus);
	}

	@Override
	public void execute(TransactionExecutor executor) {
		if(transactionStatus == null) {
			begin();
		}
		try {
			executor.execute();
			commit();
		}catch (Exception e) {
			rollback();
			logger.error("[execute] execute error", e);
		}
	}

	public TransactionStatus getTransactionStatus() {
		return transactionStatus;
	}

	public PlatformTransactionManager getPlatformTransactionManager() {
		return platformTransactionManager;
	}

	public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
		this.platformTransactionManager = platformTransactionManager;
	}
}
